package com.demo;

import java.io.FileOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import sun.misc.ProxyGenerator;

public class DynamicProxyTest {
	public static void writeProxyClassToHardDisk(String path) throws Exception {
		// 第一种方法，这种方式在刚才分析ProxyGenerator时已经知道了
		// System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", true);
		// 第二种方法
		// 获取代理类的字节码
		byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy11", IAImpl.class.getInterfaces());
		FileOutputStream out = new FileOutputStream(path);
		out.write(classFile);
		out.flush();
		out.close();
	}

	public static void main(String[] args) throws Exception {

		writeProxyClassToHardDisk("E:\\workspace2\\jucdemo\\Proxy11.class");
		/*
		 * // 添加以下的几段代码, 就可以将代理生成的字节码保存起来了 Field field =
		 * System.class.getDeclaredField("props"); field.setAccessible(true);
		 * Properties props = (Properties) field.get(null);
		 * props.put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
		 * 
		 * Package pkg = ProxyTest2.class.getPackage(); if (pkg != null) {
		 * String packagePath = pkg.getName().replace(".", File.pathSeparator);
		 * new File(packagePath).mkdirs(); }
		 * 
		 * IA a = new IAImpl(); InvocationHandlerImpl ih = new
		 * InvocationHandlerImpl(a); IA proxyA = (IA)
		 * Proxy.newProxyInstance(a.getClass().getClassLoader(),a.getClass().
		 * getInterfaces(), ih);
		 * 
		 * proxyA.a();
		 */
	}
}

interface IA {
	void a();

	int b(String str);
}

class IAImpl implements IA {

	@Override
	public void a() {
		System.out.println("IAImpl.a()");
	}

	@Override
	public int b(String str) {
		System.out.println("IAImpl.b()");
		return 0;
	}
}

class InvocationHandlerImpl implements InvocationHandler {

	private Object target;

	public InvocationHandlerImpl(Object target) {
		this.target = target;
	}

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("before...");
		Object res = method.invoke(target, args);
		System.out.println("after...");
		return res;
	}
}